;; 2010-12-17 15:15:08
;; the ediff + svn utils

(defconst es-rev-line-regexp "^r\\([0-9]+\\)[ \t]+.*\n")

(defconst es-rev-select-buffer "*es-rev-sel*")

(defvar es-buf nil)

(defvar es-buf-mode nil)

(defvar es-path nil)

(defvar es-name nil)

(defvar es-truename  nil)

(defun es-get-svn-log (fn)
  (message "calling svn log %s" fn)
  (when (= 0 (call-process "svn" nil t nil "log" fn))
    ;; setup the text props
    (goto-char (point-min))
    (while (re-search-forward es-rev-line-regexp nil t)
      (set-text-properties (match-beginning 1) (match-end 1)
                           '(mouse-face underline))
      (add-text-properties (match-beginning 1) (match-end 1)
                           '(face (:foreground "green")))
      (local-set-key [(control mouse-1)] 'es-on-clicked))))

(defun es-goto-event-point (event)
  (goto-char (posn-point (event-end event))))

(defun es-on-clicked (event)
  (interactive "e")
  (es-goto-event-point event)
  ;; get the rev
  (beginning-of-line)
  (when (and es-buf (= ?r (following-char)))
    (when (re-search-forward es-rev-line-regexp nil t)
      (let ((rev (buffer-substring-no-properties
                  (match-beginning 1) (match-end 1)))
            (revbuf (get-buffer-create "*es-rev-cmp*"))
            (tmpfile (concat "/tmp/" (make-temp-name "es"))))
        (message "ediff version %s" rev)
        (cd es-path)
        (when (= 0 (call-process "svn" nil nil nil "export" "-r" rev es-name tmpfile))
          (switch-to-buffer revbuf)
          (delete-region (point-min) (point-max))
          (insert-file-contents tmpfile)
          (delete-file tmpfile)
          (funcall es-buf-mode)
          (ediff-buffers revbuf es-buf))))))

(defun es-do ()
  (let ((fn (buffer-file-name)))
    (when fn
      ;; save the curr buffer to es-buf
      (setq es-truename (file-truename fn)
            es-name (file-name-nondirectory es-truename)
            es-path (file-name-directory es-truename)
            es-buf (current-buffer)
            es-buf-mode major-mode)
      (switch-to-buffer (get-buffer-create es-rev-select-buffer))
      (delete-region (point-min) (point-max))
      (es-get-svn-log fn))))

(defun es-do-cmd ()
  (interactive)
  (es-do))

(provide 'ediff-svn)
